/**
 * @description 事件生产者
 * @class {EventProduct}
 * @author hhx
 * @date 2024-11-26 15:11
 * @version 0.1.2
 */
export default class EventProduct {

    /**
     * @description 事件生产者集合
     * @private
     * @type {Map}
     */
    _eventProduct = null

    /**
     * @description 事件生产者构造函数
     * @public
     * @constructor
     * @param props {object} 配置对象
     */
    constructor(props = {}) {
        this.init();
    }

    /**
     * @description 实例化 基础生产者
     * @public
     * @static
     * @param props {object} 配置对象
     * @returns {EventProduct|*} 基础事件生产者实例
     */
    static instance(props = {}) {

        let instance = new EventProduct(props)

        instance.init();

        return instance;

    }

    //=========================== 内部成员 ===============================

    /**
     * @description 获取 事件集合
     * @protected
     * @override
     * @returns {Map|*} 事件集合
     */
    get eventProduct() {
        return this._eventProduct;
    }

    /**
     * @description 设置 事件集合
     * @protected
     * @override
     * @param newValue {Map|*} 事件集合
     */
    set eventProduct(newValue) {
        this._eventProduct = newValue;
    }

    //=========================== 成员方法 ===============================

    /**
     * @description 获取事件集合
     * @public
     * @return {Map} 事件集合
     */
    getEventProduct() {
        return this.eventProduct;
    }

    /**
     * @description 设置事件集合
     * @public
     * @param newValue {Map} 事件集合
     */
    setEventProduct(newValue) {
        this.eventProduct = newValue;
    }

    /**
     * @description 判断是否存在事件
     * @public
     * @param eventName {string} 事件名
     * @return {boolean} true 是 false 否
     */
    hasEventProduct(eventName) {
        return this.eventProduct.has(eventName);
    }

    //=========================== 创建方法 ===============================

    /**
     * @description 初始化
     * @protected
     * @override
     */
    init() {
        this.eventProduct = new Map();
    }


    //=========================== 构建方法 ===============================

    //=========================== 事件触发 ===============================

    /**
     * @description 触发事件
     * @public
     * @method
     * @param target 触发事件对象
     * @param {*} eventName 事件名
     * @param value {*} 参数值
     */
    triggerEvent(target, eventName, value) {

        let event = this.getTargetTriggerEvent(target)

        //触发事件
        this.executeEvent(event, eventName, value)
    }

    //=========================== 事件订阅 ===============================

    /**
     * @description 订阅事件
     * @public
     * @method
     * @param target {Object} 订阅事件对象
     * @param {*} eventName 事件名称
     * @param {function} callback 触发事件回调
     */
    subscriberEvent(target, eventName, callback) {

        let event = this.getTargetSubscriberEvent(target);

        if (event.has(eventName)) {
            this.addSubscriberEvent(event, eventName, callback);
        } else {
            this.createSubscriberEvent(event, callback, eventName);
        }
    }

    //========================== 接口方法 ==========================

    /**
     * @description 删除事件
     * @public
     * @method
     * @param eventName {*} 事件名称
     */
    clearEvents(eventName) {
        this.eventProduct.delete(eventName);
    }


    //=========================== 内部方法 ===============================

    /**
     * @description 获取触发事件对象
     * @protected
     * @param target {object} 触发事件对象
     * @return {Map} 事件集合
     */
    getTargetTriggerEvent(target) {
        return target.getModel().getEventProduct().getEventProduct();
    }

    /**
     * @description 获取目标订阅事件
     * @protected
     * @param target {Object} 目标订阅事件
     * @return {Map} 订阅事件集合
     */
    getTargetSubscriberEvent(target) {
        return target.getEventProduct().getEventProduct();
    }

    /**
     * @description 创建订阅事件
     * @protected
     * @param event {Map} 事件集合
     * @param callback {Function} 事件回调
     * @param eventName {string} 事件名
     */
    createSubscriberEvent(event, callback, eventName) {
        let eventArr = [];
        eventArr.push(callback);
        event.set(eventName, eventArr);
    }

    /**
     * @description 添加订阅事件
     * @protected
     * @param event {Map} 事件集合
     * @param eventName {string} 事件函数
     * @param callback {Function} 事件回调
     */
    addSubscriberEvent(event, eventName, callback) {

        let eventArr = event.get(eventName);
        eventArr.push(callback);
        event.set(eventName, eventArr);

    }

    /**
     * @description 事件执行
     * @protected
     * @protected
     * @param event {Map} 事件集合
     * @param eventName {string} 事件函数
     * @param value {*} 回调参数
     */
    executeEvent(event, eventName, value) {

        if (event.has(eventName)) {

            let pubsubArr = event.get(eventName);

            for (const callback of pubsubArr) {
                callback(value)
            }

        }
    }
}

